import { BaseEventOrig, View } from '@tarojs/components';
import { useCallback, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { AtActivityIndicator, AtAvatar, AtButton, AtFab, AtInput, AtModal, AtToast } from 'taro-ui';
import Taro from '@tarojs/taro';
import { EGender, TAssigneeUserInfo, TUserInfo } from '../../types';
import { TStateType } from '../../redux/reducers';
import TopIcon, { EIcon } from '../../components/top-icon/index.weapp';
import * as ActionTypes from '../../redux/action/types';

import './index.scss';

const My = () => {
  const dispatch = useDispatch();
  const userInfo: TUserInfo = useSelector((state: TStateType) => state.userInfo);
  const assigneeUserInfo: TAssigneeUserInfo = useSelector(
    (state: TStateType) => state.assigneeUserInfo
  );
  const [assgineeUser, setAssgineeUser] = useState<TAssigneeUserInfo>(assigneeUserInfo);
  const [assgineeUserOpenId, setAssgineeUserOpenId] = useState('');
  const [isOpenIdDisabled, setIsOpenIdDisabled] = useState(false);
  const [isBindDisabled, setIsBindDisabled] = useState(false);
  const [isCheckLoading, setIsCheckLoading] = useState(false);
  const [isOpenToast, setIsOpenToast] = useState(false);
  const [isShowUnBindButton, setIsShowUnBindButton] = useState(false);
  const [isOpenUnBindModal, setIsOpenUnBindModal] = useState(false);

  const [lastTapDiffTime, setLastTapDiffTime] = useState(0);
  const [errorMessage, setErrorMessage] = useState('');
  const copyUserOpenId = useCallback(() => {
    Taro.setClipboardData({
      data: userInfo.openId
    });
  }, [userInfo.openId]);

  useEffect(() => {
    setAssgineeUser(assigneeUserInfo);
    if (assigneeUserInfo.openId) {
      setIsBindDisabled(true);
    }
  }, [assigneeUserInfo]);

  const handleCheck = useCallback(() => {
    if (assgineeUserOpenId.length !== 0) {
      if (assgineeUserOpenId === userInfo.openId) {
        setErrorMessage('you cannot link yourself');
        setIsOpenToast(true);
        return;
      } else if (assgineeUserOpenId === assigneeUserInfo.openId) {
        setErrorMessage("you've already linked the user");
        setIsOpenToast(true);
        return;
      }
      setIsCheckLoading(true);
      setIsOpenIdDisabled(true);
      Taro.cloud.callFunction({
        name: 'getuserinfo',
        data: {
          openId: assgineeUserOpenId
        },
        success: function (res: any) {
          setIsCheckLoading(false);
          setIsOpenIdDisabled(false);
          if (res.result.data.length > 0) {
            const resAssginUser = res.result.data[0] as TUserInfo;
            if (resAssginUser.userLink) {
              setErrorMessage(`${resAssginUser.nickName} is already bound to someone else`);
              setIsOpenToast(true);
            } else {
              setAssgineeUser({
                avatarUrl: resAssginUser.avatarUrl,
                openId: resAssginUser.openId,
                nickName: resAssginUser.nickName
              });
            }
            setIsBindDisabled(false);
          } else {
            setErrorMessage('the user was not found');
            setIsOpenToast(true);
          }
        }
      });
    } else {
      setErrorMessage('the openid cannot be empty');
      setIsOpenToast(true);
    }
  }, [assgineeUserOpenId, assigneeUserInfo.openId, userInfo.openId]);

  const handleBind = useCallback(() => {
    setIsBindDisabled(true);
    if (userInfo.userLink) {
      // update
      // 清除旧assgineeUser的userLink
      Taro.cloud.callFunction({
        name: 'updateuserinfo',
        data: {
          openId: assigneeUserInfo.openId,
          userInfo: {
            userLink: ''
          }
        }
      });
      // 更新userLink
      Taro.cloud.callFunction({
        name: 'updateuserlink',
        data: {
          _id: userInfo.userLink,
          userGroup: { userOpenId: userInfo.openId, assgineeUserOpenId }
        },
        success: function () {
          dispatch({
            type: ActionTypes.SET_ASSIGNEEUSERINFO,
            payload: assgineeUser
          });
        }
      });
      // 同步新assineeUser的userLink
      Taro.cloud.callFunction({
        name: 'updateuserinfo',
        data: {
          openId: assgineeUser.openId,
          userInfo: {
            userLink: userInfo.userLink
          }
        },
        success: function () {
          setIsBindDisabled(false);
        }
      });
    } else {
      // create
      Taro.cloud.callFunction({
        name: 'adduserlink',
        data: {
          userGroup: { userOpenId: userInfo.openId, assgineeUserOpenId }
        },
        success: function (res: any) {
          const userLink = res.result._id;
          Taro.cloud.callFunction({
            name: 'updateuserinfo',
            data: {
              openId: userInfo.openId,
              userInfo: {
                userLink
              }
            },
            success: function () {
              dispatch({ type: ActionTypes.SET_USERLINK, payload: userLink });
            }
          });
          Taro.cloud.callFunction({
            name: 'updateuserinfo',
            data: {
              openId: assgineeUserOpenId,
              userInfo: {
                userLink
              }
            },
            success: function () {
              setIsBindDisabled(false);
              dispatch({
                type: ActionTypes.SET_ASSIGNEEUSERINFO,
                payload: assgineeUser
              });
            }
          });
        }
      });
    }
  }, [
    assgineeUser,
    assgineeUserOpenId,
    assigneeUserInfo.openId,
    dispatch,
    userInfo.openId,
    userInfo.userLink
  ]);
  // 判断双击事件
  const checkDoubleClick = useCallback(
    (e: BaseEventOrig) => {
      const curTime = e.timeStamp;
      const lastTime = lastTapDiffTime;
      if (lastTime > 0) {
        if (curTime - lastTime < 300) {
          setLastTapDiffTime(curTime);
          return true;
        } else {
          setLastTapDiffTime(curTime);
        }
      } else {
        setLastTapDiffTime(curTime);
      }
      return false;
    },
    [lastTapDiffTime]
  );

  const handleShowUnBindButton = useCallback(
    (e: BaseEventOrig) => {
      const isDoubleClick = checkDoubleClick(e);
      if (isDoubleClick) {
        setIsShowUnBindButton(pre => !pre);
      }
    },
    [checkDoubleClick]
  );

  const handleUnBindClick = useCallback(() => {
    setIsOpenUnBindModal(false);
    setIsShowUnBindButton(false);
    Taro.cloud.callFunction({
      name: 'updateuserinfo',
      data: {
        openId: userInfo.openId,
        userInfo: {
          userLink: ''
        }
      }
    });
    Taro.cloud.callFunction({
      name: 'updateuserinfo',
      data: {
        openId: assigneeUserInfo.openId,
        userInfo: {
          userLink: ''
        }
      }
    });
    Taro.cloud.callFunction({
      name: 'deleteuserlink',
      data: {
        _id: userInfo.userLink
      },
      success: function () {
        dispatch({
          type: ActionTypes.SET_ASSIGNEEUSERINFO,
          payload: {
            avatarUrl: '',
            nickName: '',
            openId: ''
          }
        });
        dispatch({ type: ActionTypes.SET_USERLINK, payload: '' });
      }
    });
  }, [assigneeUserInfo.openId, dispatch, userInfo.openId, userInfo.userLink]);

  return (
    <View className='my-page'>
      <View className='my-userinfo'>
        <View className='avatar'>
          <AtAvatar circle image={userInfo.avatarUrl} />
        </View>
        <View className='my-user-bottom'>
          <View className='my-user'>
            <TopIcon
              name={userInfo.gender === EGender.Female ? 'female' : 'male'}
              type={EIcon.Gender}
            />
            <View className='user-info user-nickname'>nick name: {userInfo.nickName}</View>
          </View>
          <View className='my-user'>
            <TopIcon name='baohusan' type={EIcon.Action} />
            <View className='user-info user-id' onClick={copyUserOpenId}>
              ID: {userInfo.openId}
            </View>
          </View>
        </View>
      </View>
      <View className='assginee-container'>
        <View className='assginee-title'>Bind</View>
        <AtInput
          name='value1'
          type='text'
          placeholder='link user id'
          value={assgineeUserOpenId}
          disabled={isOpenIdDisabled}
          onChange={(value: string) => setAssgineeUserOpenId(value)}
        />
        <AtButton type='primary' onClick={handleCheck}>
          {isCheckLoading ? (
            <AtActivityIndicator mode='center' content='Loading...' color='white' />
          ) : (
            'check'
          )}
        </AtButton>
        <View
          className={`assginee-user-container ${assgineeUser.openId ? '' : 'no-assginee-user'}`}
        >
          {assgineeUser.openId ? (
            <>
              <View className='assginee-user' onClick={handleShowUnBindButton}>
                <AtAvatar circle image={assgineeUser.avatarUrl} size='small' />
                <View className='assgine-user-name'>{assgineeUser.nickName}</View>
              </View>
              {isShowUnBindButton ? (
                <AtButton
                  type='primary'
                  className='un-bind'
                  onClick={() => setIsOpenUnBindModal(true)}
                >
                  unbind
                </AtButton>
              ) : (
                <AtButton type='primary' disabled={isBindDisabled} onClick={handleBind}>
                  {isBindDisabled ? 'be bound' : 'bind'}
                </AtButton>
              )}
            </>
          ) : (
            <View className='no-link'>you have no link to other users.</View>
          )}
        </View>
      </View>
      <AtToast
        isOpened={isOpenToast}
        text={errorMessage}
        onClose={() => {
          setErrorMessage('');
          setIsOpenToast(false);
        }}
      />
      <AtModal
        isOpened={isOpenUnBindModal}
        cancelText='Cancel'
        confirmText='Ok'
        onClose={() => setIsOpenUnBindModal(false)}
        onCancel={() => setIsOpenUnBindModal(false)}
        onConfirm={() => handleUnBindClick()}
        content='are you sure you want to unbind this user?'
      />
      <View className='fab-container'>
        <AtFab
          size='small'
          onClick={() => {
            Taro.navigateTo({
              url: `/pages/about/index`
            });
          }}
        >
          <View className='at-fab__icon at-icon at-icon-help'></View>
        </AtFab>
      </View>
    </View>
  );
};
export default My;
